package edu.gatech.cs3240;

import java.util.ArrayList;

/**
 * Represents a node in the parse tree, which contains a Token (either a 
 * terminal in the regex string (a, b, *, |, etc.) or a nonterminal (EXP, PROD,
 * etc.).  If it is a nonterminal, the list of children represent the 
 * production from that nonterminal.
 * @author VRamachandran
 */
public class ParseTreeNode {
	private ArrayList<ParseTreeNode> children;
	private Token data;
	private ParseTreeNode parent;
	
	/**
	 * Creates a Parse Tree.  Should only be called for the root node;
	 * all others are created through the addChild() method.
	 * @param t The token representing the start state.
	 */
	public ParseTreeNode(Token t) {
		this.data = t;
		this.parent = null;
		this.children = new ArrayList<ParseTreeNode>();
	}
	
	/**
	 * To be called when using a production rule.  A child should be 
	 * created for each of the tokens in the right-hand side of the 
	 * rule, in order (to preserve leftmost / rightmost derivation through
	 * array indices).
	 * @param t A token, terminal or nonterminal.
	 * @return
	 */
	public ParseTreeNode addChild(Token t) {
		ParseTreeNode n = new ParseTreeNode(t);
		children.add(n);
		n.parent = this;
		return n;
	}
	
	/**
	 * Gets the parent of this node (i.e., the Nonterminal that this
	 * token was produced from).  For the root node (start state), returns
	 * null.
	 * @return Parent node.
	 */
	public ParseTreeNode getParent() {
		return parent;
	}
	
	/**
	 * Returns the token stored in this node.
	 * @return Token
	 */
	public Token getToken() {
		return data;
	}
	
	/**
	 * Returns all the children of this node, representing the 
	 * expansion of this nonterminal.  Assuming addChild() was called
	 * in order of production, the order is preserved.
	 * @return ArrayList of children nodes.
	 */
	public ArrayList<ParseTreeNode> getChildren() {
		return children;
	}
	
	@Override
	public String toString() {
		return toString("");
	}
	
	/**
	 * Outputs an ASCIIart(!) tree representing this object and its 
	 * children.
	 * @return A cool-looking tree.
	 */
	public String toString(String pre) {
		//Figure out a way to do this.  Probably recursive, somehow.
		String childrenStrings = "";
		pre += "\t";
		for(int i = 0; i < children.size(); i++) {
			childrenStrings += pre + children.get(i).toString(pre);
		}
		return data.toString() + "\n" + childrenStrings;
	}
	
	public ParseTreeNode[] getLeafNodes() {
		ArrayList<ParseTreeNode> a = new ArrayList<ParseTreeNode>();
		
		return a.toArray(new ParseTreeNode[0]);
	}
}